package ui;


import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;

/**
 * A Screen encapsulates a state of our MIDP GUI.
 * @author Karl
 */
public abstract class Screen implements CommandListener{
    DisplayContext context;
   
    /**
     * Default commands.
     */
    private static Command[] commands;
    static {
        commands = new Command[2];
        commands[0] = new Command("Cancel",Command.CANCEL, 0);
        commands[1] = new Command("Ok", Command.OK,0);
    }
    
    /**
     * Every screen shares an Empowered worker thread. Runnable jobs are
     * queued up in his thread by calling worker.runCode().
     *
     * As an example, we have the ScreenChanger class that can generate
     * Runnables that will change the screen, which can be passed to
     * the worker's runCode method.
     */
    protected static EmpoweredWorker worker;
    static {
        worker = new EmpoweredWorker();
    }
    
    /** Creates a new instance of Screen */
    protected Screen(DisplayContext context) {
        this.context = context;
    }
    
    /**
     * Make this screen visible on the display, and register the
     * commands with the displayable.
     */
    public void enter() {
        Display display = context.getDisplay();
        Displayable displayable = getDisplayable();
        Command[] commands = getCommands();
        for(int ii = 0; ii < commands.length; ii++)
            displayable.addCommand(commands[ii]);
        displayable.setCommandListener(this);
        displayable.setTitle(getTitle() );
        display.setCurrent(displayable );
    }
    
    /**
     * @return The DisplayContext for this screen.
     */
    protected DisplayContext getContext() {
        return context;
    }
    
    /**
     * Disables commands and runs target in a separate thread.
     */
    public void switchScreen(Screen target) {
        // Disable commands..
        //getDisplayable().setCommandListener(null);
        // Switch screen in a separate thread!
        worker.runCode(ScreenChanger.toScreen(target) );
    }
    
    /**
     * Adds the "Ok" and "Cancel" commands as defaults for subclasses to use.
     */
    protected Command[] getDefaultCommands() {
        return commands;
    }
    
    /**
     * Subclasses should return their Displayable.
     * This method should not be used for construction, as it will be
     * called frequently during execution.
     *
     * Not used outside of the Screen component.
     */
    protected abstract Displayable getDisplayable();
    
    /**
     * Subclases should return the set of commands that they want to add
     */
    protected abstract Command[] getCommands();
    
    /**
     * Subclasses should return the title they want to show
     */
    protected abstract String getTitle();
}
